package com.dq.rbac.commons.security;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dq.rbac.entity.SysMenu;
import com.dq.rbac.entity.SysRole;
import com.dq.rbac.entity.SysUser;
import com.dq.rbac.service.SysMenuService;
import com.dq.rbac.service.SysRoleService;
import com.dq.rbac.service.SysUserService;
import com.dq.rbac.utils.JWTUtils;
import com.dq.rbac.utils.JwtUtil;
import com.dq.rbac.vo.R;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @project: rbac
 * @ClassName: 自定义登陆成功处理器
 * @author: dq
 * @creat: 2022/12/26 14:19
 */
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    //用户登录成功返回 权限List
    @Resource
    private SysUserService userService;
    @Resource
    private SysRoleService roleService;
    @Resource
    private SysMenuService menuService;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        //根据用户名生成token
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        String username = authentication.getName();
        System.out.println(authentication);
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("username", username);
        String token = JwtUtil.generate(stringObjectHashMap);

        //获取当前用户信息
        SysUser user = userService.getByUserName(username);
        //根据用户id 获取当前用户的所有角色
        List<SysRole> roleList = roleService.list(new LambdaQueryWrapper<SysRole>()
                .inSql(SysRole::getId, "SELECT role_id FROM sys_user_role WHERE user_id = " + user.getId()));

        //单独封装到user 的 roles中去
        user.setRoles(roleList.stream().map(SysRole::getName).collect(Collectors.joining(",")));

        //遍历所有角色,获取所有角色的菜单权限，而且不重复
        Set<SysMenu> menuSet = new HashSet<>();
        for (SysRole sysRole : roleList) {
            //SELECT * from sys_menu where id IN (SELECT menu_id FROM sys_role_menu WHERE role_id = 1)
            List<SysMenu> userMenuList = menuService.list(new LambdaQueryWrapper<SysMenu>().inSql(SysMenu::getId, "SELECT menu_id FROM sys_role_menu WHERE role_id = " + sysRole.getId()));
            for (SysMenu sysMenu : userMenuList) {
                menuSet.add(sysMenu);
            }
        }
        List<SysMenu> sysMenuList = new ArrayList<>(menuSet);
        sysMenuList.sort(Comparator.comparing(SysMenu::getOrderNum));

        //返回一个Tree
        List<SysMenu> menuList=menuService.buildTreeMenu(sysMenuList);

        //定义返回内容
        byte[] result = JSONUtil.toJsonStr(R.ok().data("authorization", token).data("currentUser", user).data("menuList",menuList)).getBytes(StandardCharsets.UTF_8);
        outputStream.write(result);
        outputStream.flush();
        outputStream.close();
    }
}
